﻿using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using SimpleCmsWithAbp.Contents;
using SimpleCmsWithAbp.Helper;
using SimpleCmsWithAbp.Tags.Dto;

namespace SimpleCmsWithAbp.Tags
{
    public class TagAppService : AsyncCrudAppService<Tag,TagDto,long>, ITagAppService
    {
        public readonly IRepository<ContentTag, long> _ContentTagRepository;

        public TagAppService(IRepository<Tag, long> repository, IRepository<ContentTag,long> contentTagRepository) : base(repository)
        {
            _ContentTagRepository = contentTagRepository;
        }

        public async Task<TagDto> Create(CreateTagDto input)
        {
            CheckCreatePermission();
            var entity = ObjectMapper.Map<Tag>(input);
            entity.TenantId = AbpSession.TenantId ?? 1;
            await Repository.InsertAsync(entity);
            await CurrentUnitOfWork.SaveChangesAsync();

            return MapToEntityDto(entity);

        }

        public async Task<PagedResultDto<TagDto>> GetAll(GetAllTagInputDto input)
        {
            CheckGetAllPermission();

            var query = Repository.GetAll().AsQueryable();

            if (!string.IsNullOrEmpty(input.Query))
                query = query.Where(m =>m.Name.Contains(input.Query));

            var totalCount = await AsyncQueryableExecuter.CountAsync(query);

            query = ApplySorting(query, input);
            query = ApplyPaging(query, input);

            var entities = await AsyncQueryableExecuter.ToListAsync(query);

            if (input.Cid != null)
            {
                var tags = await _ContentTagRepository.GetAllIncluding(m=>m.Tag).Where(m => m.ContentId == input.Cid).Select(m=>m.Tag).ToListAsync();
                entities = entities.Union(tags).ToList();
            }

            return new PagedResultDto<TagDto>(
                totalCount,
                entities.Select(base.MapToEntityDto).ToList()
            );
        }

        public async Task Delete(DeleteInputDto input)
        {
            CheckDeletePermission();
            var entities = Repository.GetAllIncluding(m=>m.ContentTags).Where(m=>input.Id.Contains(m.Name));
            foreach (var entity in entities)
            {
                if(!entity.ContentTags.Any()) await Repository.DeleteAsync(entity.Id);
            }
        }

        [NonAction]
        public override Task<TagDto> Create(TagDto input)
        {
            return base.Create(input);
        }

        [NonAction]
        public override Task<PagedResultDto<TagDto>> GetAll(PagedAndSortedResultRequestDto input)
        {
            return base.GetAll(input);
        }

        [NonAction]
        public override Task<TagDto> Update(TagDto input)
        {
            return base.Update(input);
        }

        [NonAction]
        public override Task Delete(EntityDto<long> input)
        {
            return base.Delete(input);
        }
    }
}